﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartMathLibrary
{
    /// <summary>
    /// This class provides methods to interpolate a linear spline out of specified points. 
    /// </summary>
    [Serializable]
    public class LinearSplineInterpolation
    {
        /// <summary>
        /// The points for the interpolation.
        /// </summary>
        private readonly Point2DCollection interpolationPoints;

        /// <summary>
        /// Initializes a new instance of the <see cref="LinearSplineInterpolation"/> class.
        /// </summary>
        /// <param name="interpolationPoints">The points for the interpolation.</param>
        public LinearSplineInterpolation(Point2DCollection interpolationPoints)
        {
            if (interpolationPoints == (Point2DCollection) null)
            {
                throw new ArgumentNullException("interpolationPoints");
            }

            this.interpolationPoints = interpolationPoints;
        }

        /// <summary>
        /// Interpolates the linear splines with the specified points.
        /// </summary>
        /// <returns>The interpolated linear spline.</returns>
        public LinearSpline Interpolate()
        {
            if (this.interpolationPoints.Count < 2)
            {
                throw new ArgumentException("Minimum two points were needed for an interpolation.");
            }

            LinearSpline result = new LinearSpline();

            this.interpolationPoints.Sort();

            for (int i = 1; i < this.interpolationPoints.Count; i++)
            {
                LinearFunctionInterpolation interpolation = new LinearFunctionInterpolation
                    (this.interpolationPoints[i - 1], this.interpolationPoints[i]);

                result.Add(new LinearSplineComponent(interpolation.Interpolate(),
                                                     this.interpolationPoints[i - 1], this.interpolationPoints[i]));
            }

            return result;
        }
    }
}